package com.example.jpademo.controller;

import com.example.jpademo.dao.EtlAppDao;
import com.example.jpademo.dao.EtlAppInfoDao;
import com.example.jpademo.model.EtlApp;
import com.example.jpademo.model.EtlAppInfo;
import com.example.jpademo.vo.AppConfVo;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.query.JpaQueryMethodFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.*;
import javax.servlet.http.HttpSession;
import java.text.DateFormat;
import java.util.*;

@RestController
@RequestMapping("/demo")
public class DemoController {
    private static final String OK="OK";
    @Resource
    EtlAppDao etlAppDao;
    @Resource
    EtlAppInfoDao etlAppInfoDao;
    /**PersistenceContext 解决线程安全问题*/
    @PersistenceContext
    private EntityManager entityManager;
    @GetMapping("/list")
    public String list(HttpSession session){
        List<EtlApp> list = etlAppDao.findAll();
        return list.toString();
    }
    @GetMapping("/list/{id}")
    public String list(@PathVariable("id")String id){
        Optional<EtlApp> optional = etlAppDao.findById(id);
        return optional.isPresent()?optional.get().toString():null;
    }
    @GetMapping("/test")
    public String save() {
        Date now = new Date();
        EtlApp app = new EtlApp();
//        app.setId(UUID.randomUUID().toString());
        app.setCode(UUID.randomUUID().toString());
        app.setName(now.getHours()+":"+now.getMinutes() +":"+now.getSeconds());
        app.setDes("des");
        app.setEtlAppSysDes("sysdes");
        app.setEtlSys("sys");
        app.setDescription(app.toString());
        etlAppDao.save(app);
        EtlAppInfo info = new EtlAppInfo();
        info.setAppId(app.getId());
        info.setInfoName(app.getName());
        info.setInputDate(now);

        etlAppInfoDao.save(info);
        //Specification
        Specification<EtlAppInfo> specification = (Specification<EtlAppInfo>) (root, query, cb) -> {
            Predicate predicate = cb.conjunction();
            if (info.getId() != null) {
                predicate.getExpressions().add(cb.equal(root.get("id"), info.getId()));
            }
            if (StringUtils.hasLength(app.getId())) {
                predicate.getExpressions().add(cb.equal(root.get("appId"), "%" + app.getId() + "%"));
            }
            // 多字段排序
            List<Order> orders = new ArrayList<>();
            orders.add(cb.desc(root.get("appId")));
            orders.add(cb.desc(root.get("inputDate")));
            query.orderBy(orders);
            // 单字段排序
            // query.orderBy(cb.desc(root.get("inputDate")));
            return predicate;
        };
        //Example
        etlAppInfoDao.findAll(specification);
        etlAppInfoDao.findAll(specification,PageRequest.of(0, 10));
        List<EtlAppInfo> etlAppInfos = etlAppInfoDao.selectMaxId("id",PageRequest.of(0, 1));

        EtlAppInfo info1 = new EtlAppInfo();
        info1.setAppId(info.getAppId());
        etlAppInfoDao.findAll(Example.of(info1));
        Page<AppConfVo> vo = etlAppDao.findAppConfVo(PageRequest.of(0, 10));
//        Page<AppConfVo> vo1 = etlAppDao.initAppConfVo(PageRequest.of(0, 10));

        //select new com.example.jpademo.vo.AppConfVo(app.id,info.appId,info.infoName,info.inputDate) from EtlApp app ,EtlAppInfo info where app.id = info.appId

        //返回自定义对象连表查
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        //StudentResult只是Student的部分字段
        CriteriaQuery<AppConfVo> criteriaQuery = criteriaBuilder.createQuery(AppConfVo.class);

        Root<EtlApp> root = criteriaQuery.from(EtlApp.class);
        Root<EtlAppInfo> einfo = criteriaQuery.from(EtlAppInfo.class);
        //返回自定义对象
        criteriaQuery.multiselect(root.get("id"), einfo.get("appId"),einfo.get("infoName"),einfo.get("inputDate"));

        List<Predicate> predicates = new ArrayList<>();
        predicates.add(criteriaBuilder.equal(root.get("id"),einfo.get("appId")));
        //返回自定义对象
        List<AppConfVo> resultList = entityManager.createQuery(criteriaQuery).getResultList();
        System.out.println(resultList);
        //返回自定义对象 自定义sql 可动态拼接
        List<AppConfVo> resultList1 = entityManager.createQuery("select new com.example.jpademo.vo.AppConfVo(app.id,info.appId,info.infoName,info.inputDate) from EtlApp app ,EtlAppInfo info where app.id = info.appId ").getResultList();
        System.out.println(resultList1);


        EtlAppInfo info2 = new EtlAppInfo();
        info2.setAppId("8533431b-375a-4903-ae4c-a3a51669");
        info2.setId(1L);
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("appId",ExampleMatcher.GenericPropertyMatchers.contains())
//        .withMatcher("appId",ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("id",ExampleMatcher.GenericPropertyMatchers.exact());

        etlAppInfoDao.findAll( Example.of(info2, matcher));
        return OK;
    }
}
